package com.lcj.common.util;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.lcj.common.exception.AochException;

import com.qcloud.cos.COSClient;
import com.qcloud.cos.ClientConfig;
import com.qcloud.cos.auth.BasicCOSCredentials;
import com.qcloud.cos.auth.COSCredentials;
import com.qcloud.cos.http.HttpMethodName;
import com.qcloud.cos.http.HttpProtocol;
import com.qcloud.cos.model.*;
import com.qcloud.cos.model.ciModel.auditing.ImageAuditingRequest;
import com.qcloud.cos.model.ciModel.auditing.ImageAuditingResponse;
import com.qcloud.cos.region.Region;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.net.URL;
import java.util.*;

/**
 * 腾讯云对象存储服务工具类
 * @author lcj
 */
@Component
public class CosUtil {
    @Value("${tencent.cloud.appId}")
    private String appId;

    @Value("${tencent.cloud.secretId}")
    private String secretId;

    @Value("${tencent.cloud.secretKey}")
    private String secretKey;

    @Value("${tencent.cloud.region-public}")
    private String regionPublic;

    @Value("${tencent.cloud.bucket-public}")
    private String bucketPublic;

    @Value("${tencent.cloud.region-private}")
    private String regionPrivate;

    @Value("${tencent.cloud.bucket-private}")
    private String bucketPrivate;

    public static String PUBLIC = "public";
    public static String PRIVATE = "private";

    /**
     * 获取访问存储桶的连接
     * @param type 存储桶类型:pubic,private
     * @return 连接客户端对象
     */
    private COSClient getCosClient(String type) {
        String regin = PUBLIC.equals(type) ? regionPublic : regionPrivate;
        COSCredentials cred = new BasicCOSCredentials(secretId, secretKey);
        ClientConfig clientConfig = new ClientConfig(new Region(regin));
        clientConfig.setHttpProtocol(HttpProtocol.https);
        COSClient cosClient = new COSClient(cred, clientConfig);
        return cosClient;
    }


    /**
     * 向存储桶上传文件
     * @param bucketType 存储桶类型: public, private
     * @param file 本地文件对象
     * @param path 云端地址
     * @return 访问地址信息
     * @throws IOException
     */
    public HashMap uploadFile(String bucketType,MultipartFile file, String path) throws IOException {
        String bucket = null;
        String region = null;
        if(PUBLIC.equals(bucketType)) {
            bucket = bucketPublic;
            region = regionPublic;
        } else {
            bucket = bucketPrivate;
            region = regionPrivate;
        }
        //上传文件的名字
        String fileName = file.getOriginalFilename();
        //文件后缀名
        String fileType = fileName.substring(fileName.lastIndexOf("."));
        //避免重名图片在云端覆盖，所以用UUID作为文件名
        path += IdUtil.simpleUUID() + fileType;

        //元数据信息
        ObjectMetadata meta = new ObjectMetadata();
        meta.setContentLength(file.getSize());
        meta.setContentEncoding("UTF-8");
        meta.setContentType(file.getContentType());

        //向存储桶中保存文件
        PutObjectRequest putObjectRequest = new PutObjectRequest(bucket, path, file.getInputStream(), meta);
        putObjectRequest.setStorageClass(StorageClass.Standard);
        COSClient client = getCosClient(bucketType);
        PutObjectResult putObjectResult = client.putObject(putObjectRequest);

        //合成外网访问地址
        HashMap map = new HashMap();
        map.put("url", "https://" + bucket + ".cos." + region + ".myqcloud.com" + path);
        map.put("path", path);

        //如果保存的是图片，用数据万象服务对图片内容审核
        if (List.of(".jpg", ".jpeg", ".png", ".gif", ".bmp").contains(fileType)) {
            //审核图片内容
            ImageAuditingRequest request = new ImageAuditingRequest();
            request.setBucketName(bucket);
            //辨别黄色、暴力、政治和广告内容
            request.setDetectType("porn,terrorist,politics,ads");
            request.setObjectKey(path);
            //执行审查
            ImageAuditingResponse response = client.imageAuditing(request);

            if (!response.getPornInfo().getHitFlag().equals("0")
                    || !response.getTerroristInfo().getHitFlag().equals("0")
                    || !response.getPoliticsInfo().getHitFlag().equals("0")
                    || !response.getAdsInfo().getHitFlag().equals("0")
            ) {
                //删除违规图片
                client.deleteObject(bucket, path);
                throw new AochException("图片内容不合规");
            }
        }
        client.shutdown();
        return map;
    }

    /**
     * 获取私有读写文件的临时URL外网访问地址
     * @param path 云端路径
     * @return 临时访问地址
     */
    public String getPrivateFileUrl(String path) {
        if(StrUtil.isEmpty(path)) {
            return "";
        }
        COSClient client = getCosClient(PRIVATE);
        GeneratePresignedUrlRequest request =
                new GeneratePresignedUrlRequest(bucketPrivate, path, HttpMethodName.GET);
        //设置临时URL有效期为5分钟
        Date expiration = DateUtil.offsetMinute(new Date(), 5);
        request.setExpiration(expiration);
        URL url = client.generatePresignedUrl(request);
        client.shutdown();
        return url.toString();
    }

    /**
     * 刪除存储桶的文件
     * @param type 存储桶类型:public,private
     * @param paths 云端路径
     */
    public void deleteFile(String type, String[] paths) {
        String bucket = null;
        bucket = PUBLIC.equals(type) ? bucketPublic : bucketPrivate;
        COSClient client = getCosClient(type);
        for (String path : paths) {
            client.deleteObject(bucket, path);
        }
        client.shutdown();
    }

}